Skip to content

Add length check in Doc::data_len()#13133

Merged
masaori335 merged 1 commit into
apache:masterfrom
masaori335:asf-master-fix-cache-doc
Jun 2, 2026
Merged

Add length check in Doc::data_len()#13133
masaori335 merged 1 commit into
apache:masterfrom
masaori335:asf-master-fix-cache-doc

Conversation

@masaori335

Copy link
Copy Markdown
Contributor

To avoid underflow.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a defensive length check to Doc::data_len() in the cache layer so malformed Doc::len / hlen combinations no longer underflow when computing payload length.

Changes:

  • Add a guard in Doc::data_len() to return 0 when the fragment length is not large enough to contain the Doc prefix plus header.
  • Preserve the existing payload-length computation for valid cache documents.

Comment thread src/iocore/cache/P_CacheDoc.h
Comment thread src/iocore/cache/P_CacheDoc.h

@bryancall bryancall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good hardening. len is the unrounded on-disk fragment length (uint32_t), and since sizeof(self_type) is size_t, this->len - sizeof(self_type) - this->hlen promotes to 64-bit and underflows to a huge value when len < sizeof(Doc) + hlen, then truncates back to a bogus large uint32_t. On a corrupt or truncated doc that bogus length flows into new_IOBufferBlock() sizes and read lengths in StripeSM/CacheRead, so clamping to 0 closes an over-read. Boundary is right: <= returns 0 at equality, which is what the subtraction produced there anyway, and the callers I checked all tolerate a 0-length result.

Worth a follow-up: the deeper fix is to validate len >= prefix_len() once when the Doc is read off the stripe and treat a violation as a cache miss, rather than hardening the accessor (similar to the recent m_frag_offset_count unmarshal validation). Two related spots share this: test_Stripe.cc sizes allocations directly from data_len(), and traffic_cache_tool/CacheDefs.cc has an independent copy of Doc::data_len() with the same underflow.

@masaori335

Copy link
Copy Markdown
Contributor Author

We need to decide what we should do with traffic_cache_tool. Does anybody use it?

@masaori335 masaori335 merged commit e78ed66 into apache:master Jun 2, 2026
19 checks passed
@github-project-automation github-project-automation Bot moved this to For v10.2.0 in ATS v10.2.x Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: For v10.2.0

Development

Successfully merging this pull request may close these issues.

3 participants